﻿using Microsoft.Extensions.Logging;
using RotovapPlatform.Domain.Common;
using RotovapPlatform.Domain.Services.Data;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using static RotovapPlatform.Domain.Business.Machine.Enums.ExperimentConfigEnums;

namespace RotovapPlatform.Application.Services.Data
{
	/// <summary>
	/// 数据记录应用服务实现
	/// 负责协调数据记录的应用层功能
	/// </summary>
	public class DataRecordingAppService : IDataRecordingAppService
	{
		private readonly ILogger<DataRecordingAppService> _logger;
		private readonly IDataRecordingDomainService _dataRecordingService;
		private readonly List<Func<AlarmRecord, Task>> _alarmCallbacks = new List<Func<AlarmRecord, Task>>();

		/// <summary>
		/// 构造函数
		/// </summary>
		/// <param name="logger">日志记录器</param>
		/// <param name="dataRecordingService">数据记录领域服务</param>
		public DataRecordingAppService(ILogger<DataRecordingAppService> logger, IDataRecordingDomainService dataRecordingService)
		{
			_logger = logger;
			_dataRecordingService = dataRecordingService;
		}

		/// <summary>
		/// 获取设备参数历史记录
		/// </summary>
		/// <param name="experimentId">实验ID</param>
		/// <param name="startTime">开始时间</param>
		/// <param name="endTime">结束时间</param>
		/// <param name="interval">采样间隔（秒），用于数据降采样</param>
		/// <returns>设备参数历史记录</returns>
		public async Task<List<DeviceParameters>> GetDeviceParametersHistoryAsync(
			Guid? experimentId, DateTime startTime, DateTime endTime, int? interval = null)
		{
			try
			{
				_logger.LogInformation($"获取设备参数历史记录: 实验ID={experimentId}, 开始时间={startTime}, 结束时间={endTime}, 间隔={interval}秒");
				var parameters = await _dataRecordingService.GetDeviceParametersHistoryAsync(experimentId, startTime, endTime);

				// 如果指定了采样间隔，则进行降采样处理
				if (interval.HasValue && interval.Value > 0 && parameters.Count > 0)
				{
					return DownsampleDeviceParameters(parameters, interval.Value);
				}

				return parameters;
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "获取设备参数历史记录时发生错误");
				return new List<DeviceParameters>();
			}
		}

		/// <summary>
		/// 获取实验状态历史记录
		/// </summary>
		/// <param name="experimentId">实验ID</param>
		/// <param name="startTime">开始时间</param>
		/// <param name="endTime">结束时间</param>
		/// <returns>实验状态历史记录</returns>
		public async Task<List<ExperimentStatusRecord>> GetExperimentStatusHistoryAsync(
			Guid experimentId, DateTime startTime, DateTime endTime)
		{
			try
			{
				_logger.LogInformation($"获取实验状态历史记录: 实验ID={experimentId}, 开始时间={startTime}, 结束时间={endTime}");
				return await _dataRecordingService.GetExperimentStatusHistoryAsync(experimentId, startTime, endTime);
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "获取实验状态历史记录时发生错误");
				return new List<ExperimentStatusRecord>();
			}
		}

		/// <summary>
		/// 获取实验结果
		/// </summary>
		/// <param name="experimentId">实验ID</param>
		/// <returns>实验结果</returns>
		public async Task<ExperimentResult> GetExperimentResultAsync(Guid experimentId)
		{
			try
			{
				_logger.LogInformation($"获取实验结果: 实验ID={experimentId}");
				return await _dataRecordingService.GetExperimentResultAsync(experimentId);
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "获取实验结果时发生错误");
				return new ExperimentResult
				{
					ExperimentId = experimentId,
					IsSuccessful = false,
					ErrorMessage = "获取实验结果时发生错误: " + ex.Message
				};
			}
		}

		/// <summary>
		/// 获取实验组结果
		/// </summary>
		/// <param name="experimentGroupId">实验组ID</param>
		/// <returns>实验结果列表</returns>
		public async Task<List<ExperimentResult>> GetExperimentGroupResultsAsync(Guid experimentGroupId)
		{
			try
			{
				_logger.LogInformation($"获取实验组结果: 实验组ID={experimentGroupId}");
				// TODO: 实现实验组结果获取逻辑
				return new List<ExperimentResult>();
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "获取实验组结果时发生错误");
				return new List<ExperimentResult>();
			}
		}

		/// <summary>
		/// 获取系统事件历史记录
		/// </summary>
		public async Task<PagedResult<SystemEvent>> GetSystemEventHistoryAsync(
			DateTime startTime, DateTime endTime, List<SystemEventType> eventTypes = null,
			List<EventSeverity> severities = null, int pageIndex = 0, int pageSize = 50)
		{
			try
			{
				_logger.LogInformation($"获取系统事件历史记录: 开始时间={startTime}, 结束时间={endTime}, 页索引={pageIndex}, 页大小={pageSize}");
				var events = await _dataRecordingService.GetSystemEventHistoryAsync(startTime, endTime, eventTypes);

				// 实现分页逻辑
				return PaginateResults(events, pageIndex, pageSize);
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "获取系统事件历史记录时发生错误");
				return new PagedResult<SystemEvent> { PageIndex = pageIndex, PageSize = pageSize };
			}
		}

		/// <summary>
		/// 获取报警历史记录
		/// </summary>
		public async Task<PagedResult<AlarmRecord>> GetAlarmHistoryAsync(
			DateTime startTime, DateTime endTime, List<AlarmType> alarmTypes = null,
			List<AlarmSeverity> severities = null, bool includeAcknowledged = true,
			int pageIndex = 0, int pageSize = 50)
		{
			try
			{
				_logger.LogInformation($"获取报警历史记录: 开始时间={startTime}, 结束时间={endTime}, 包含已确认={includeAcknowledged}, 页索引={pageIndex}, 页大小={pageSize}");
				var alarms = await _dataRecordingService.GetAlarmHistoryAsync(startTime, endTime, alarmTypes);

				// 过滤已确认的报警
				if (!includeAcknowledged)
				{
					alarms = alarms.FindAll(a => !a.IsAcknowledged);
				}

				// 实现分页逻辑
				return PaginateResults(alarms, pageIndex, pageSize);
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "获取报警历史记录时发生错误");
				return new PagedResult<AlarmRecord> { PageIndex = pageIndex, PageSize = pageSize };
			}
		}

		/// <summary>
		/// 确认报警
		/// </summary>
		public async Task<OperationResult> AcknowledgeAlarmAsync(
			Guid alarmId, string acknowledgedBy, string acknowledgementNotes = null)
		{
			try
			{
				_logger.LogInformation($"确认报警: 报警ID={alarmId}, 确认用户={acknowledgedBy}");
				// TODO: 实现报警确认逻辑
				return new OperationResult { Success = true };
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "确认报警时发生错误");
				return new OperationResult { Success = false, Message = ex.Message };
			}
		}

		/// <summary>
		/// 批量确认报警
		/// </summary>
		public async Task<OperationResult> AcknowledgeAlarmsAsync(
			List<Guid> alarmIds, string acknowledgedBy, string acknowledgementNotes = null)
		{
			try
			{
				_logger.LogInformation($"批量确认报警: 报警数量={alarmIds.Count}, 确认用户={acknowledgedBy}");
				// TODO: 实现批量报警确认逻辑
				return new OperationResult { Success = true };
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "批量确认报警时发生错误");
				return new OperationResult { Success = false, Message = ex.Message };
			}
		}

		/// <summary>
		/// 导出实验数据
		/// </summary>
		public async Task<OperationResult> ExportExperimentDataAsync(
			Guid experimentId, ExportFormat exportFormat, string filePath)
		{
			try
			{
				_logger.LogInformation($"导出实验数据: 实验ID={experimentId}, 格式={exportFormat}, 路径={filePath}");
				return await _dataRecordingService.ExportExperimentDataAsync(experimentId, exportFormat, filePath);
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "导出实验数据时发生错误");
				return new OperationResult { Success = false, Message = ex.Message };
			}
		}

		/// <summary>
		/// 导出实验组数据
		/// </summary>
		public async Task<OperationResult> ExportExperimentGroupDataAsync(
			Guid experimentGroupId, ExportFormat exportFormat, string filePath)
		{
			try
			{
				_logger.LogInformation($"导出实验组数据: 实验组ID={experimentGroupId}, 格式={exportFormat}, 路径={filePath}");
				return await _dataRecordingService.ExportExperimentGroupDataAsync(experimentGroupId, exportFormat, filePath);
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "导出实验组数据时发生错误");
				return new OperationResult { Success = false, Message = ex.Message };
			}
		}

		/// <summary>
		/// 导出系统事件数据
		/// </summary>
		public async Task<OperationResult> ExportSystemEventDataAsync(
			DateTime startTime, DateTime endTime, List<SystemEventType> eventTypes,
			ExportFormat exportFormat, string filePath)
		{
			try
			{
				_logger.LogInformation($"导出系统事件数据: 开始时间={startTime}, 结束时间={endTime}, 格式={exportFormat}, 路径={filePath}");
				// TODO: 实现系统事件数据导出逻辑
				return new OperationResult { Success = true };
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "导出系统事件数据时发生错误");
				return new OperationResult { Success = false, Message = ex.Message };
			}
		}

		/// <summary>
		/// 导出报警数据
		/// </summary>
		public async Task<OperationResult> ExportAlarmDataAsync(
			DateTime startTime, DateTime endTime, List<AlarmType> alarmTypes,
			ExportFormat exportFormat, string filePath)
		{
			try
			{
				_logger.LogInformation($"导出报警数据: 开始时间={startTime}, 结束时间={endTime}, 格式={exportFormat}, 路径={filePath}");
				// TODO: 实现报警数据导出逻辑
				return new OperationResult { Success = true };
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "导出报警数据时发生错误");
				return new OperationResult { Success = false, Message = ex.Message };
			}
		}

		/// <summary>
		/// 获取当前活跃报警
		/// </summary>
		public async Task<List<AlarmRecord>> GetActiveAlarmsAsync()
		{
			try
			{
				_logger.LogInformation("获取当前活跃报警");
				// TODO: 实现获取活跃报警逻辑
				return new List<AlarmRecord>();
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "获取当前活跃报警时发生错误");
				return new List<AlarmRecord>();
			}
		}

		/// <summary>
		/// 获取实验数据统计
		/// </summary>
		public async Task<ExperimentDataStatistics> GetExperimentDataStatisticsAsync(Guid experimentId)
		{
			try
			{
				_logger.LogInformation($"获取实验数据统计: 实验ID={experimentId}");
				// TODO: 实现实验数据统计逻辑
				return new ExperimentDataStatistics { ExperimentId = experimentId };
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "获取实验数据统计时发生错误");
				return new ExperimentDataStatistics { ExperimentId = experimentId };
			}
		}

		/// <summary>
		/// 获取实验组数据统计
		/// </summary>
		public async Task<ExperimentGroupDataStatistics> GetExperimentGroupDataStatisticsAsync(Guid experimentGroupId)
		{
			try
			{
				_logger.LogInformation($"获取实验组数据统计: 实验组ID={experimentGroupId}");
				// TODO: 实现实验组数据统计逻辑
				return new ExperimentGroupDataStatistics { ExperimentGroupId = experimentGroupId };
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "获取实验组数据统计时发生错误");
				return new ExperimentGroupDataStatistics { ExperimentGroupId = experimentGroupId };
			}
		}

		/// <summary>
		/// 清理历史数据
		/// </summary>
		public async Task<OperationResult> CleanupHistoricalDataAsync(DateTime beforeDate, List<DataType> dataTypes)
		{
			try
			{
				_logger.LogInformation($"清理历史数据: 日期={beforeDate}, 数据类型数量={dataTypes.Count}");
				return await _dataRecordingService.CleanupHistoricalDataAsync(beforeDate, dataTypes);
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "清理历史数据时发生错误");
				return new OperationResult { Success = false, Message = ex.Message };
			}
		}

		/// <summary>
		/// 备份数据
		/// </summary>
		public async Task<OperationResult> BackupDataAsync(string backupPath, List<DataType> dataTypes)
		{
			try
			{
				_logger.LogInformation($"备份数据: 路径={backupPath}, 数据类型数量={dataTypes.Count}");
				return await _dataRecordingService.BackupDataAsync(backupPath, dataTypes);
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "备份数据时发生错误");
				return new OperationResult { Success = false, Message = ex.Message };
			}
		}

		/// <summary>
		/// 恢复数据
		/// </summary>
		public async Task<OperationResult> RestoreDataAsync(string backupPath)
		{
			try
			{
				_logger.LogInformation($"恢复数据: 路径={backupPath}");
				return await _dataRecordingService.RestoreDataAsync(backupPath);
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "恢复数据时发生错误");
				return new OperationResult { Success = false, Message = ex.Message };
			}
		}

		/// <summary>
		/// 注册报警回调
		/// </summary>
		public void RegisterAlarmCallback(Func<AlarmRecord, Task> callback)
		{
			_logger.LogInformation("注册报警回调");
			//_alarmCallbacks.Add(callback);
		}

		#region 辅助方法

		/// <summary>
		/// 对设备参数进行降采样处理
		/// </summary>
		/// <param name="parameters">原始设备参数列表</param>
		/// <param name="intervalSeconds">采样间隔（秒）</param>
		/// <returns>降采样后的设备参数列表</returns>
		private List<DeviceParameters> DownsampleDeviceParameters(List<DeviceParameters> parameters, int intervalSeconds)
		{
			if (parameters.Count <= 1 || intervalSeconds <= 0)
			{
				return parameters;
			}

			var result = new List<DeviceParameters>();
			var intervalTimeSpan = TimeSpan.FromSeconds(intervalSeconds);
			var lastTimestamp = parameters[0].Timestamp;

			// 添加第一个点
			result.Add(parameters[0]);

			// 按照采样间隔添加数据点
			for (int i = 1; i < parameters.Count; i++)
			{
				if (parameters[i].Timestamp - lastTimestamp >= intervalTimeSpan)
				{
					result.Add(parameters[i]);
					lastTimestamp = parameters[i].Timestamp;
				}
			}

			// 确保添加最后一个点
			if (result.Count > 0 && result[result.Count - 1] != parameters[parameters.Count - 1])
			{
				result.Add(parameters[parameters.Count - 1]);
			}

			return result;
		}

		/// <summary>
		/// 对结果进行分页处理
		/// </summary>
		/// <typeparam name="T">数据类型</typeparam>
		/// <param name="items">原始数据列表</param>
		/// <param name="pageIndex">页索引</param>
		/// <param name="pageSize">页大小</param>
		/// <returns>分页结果</returns>
		private PagedResult<T> PaginateResults<T>(List<T> items, int pageIndex, int pageSize)
		{
			if (pageSize <= 0)
			{
				pageSize = 50;
			}

			if (pageIndex < 0)
			{
				pageIndex = 0;
			}

			var totalCount = items.Count;
			var startIndex = pageIndex * pageSize;

			// 确保起始索引有效
			if (startIndex >= totalCount)
			{
				startIndex = Math.Max(0, totalCount - pageSize);
				pageIndex = startIndex / pageSize;
			}

			// 获取当前页的数据
			var pagedItems = items
				.Skip(startIndex)
				.Take(pageSize)
				.ToList();

			return new PagedResult<T>
			{
				Items = pagedItems,
				TotalCount = totalCount,
				PageIndex = pageIndex,
				PageSize = pageSize
			};
		}

		#endregion
	}
}
